#!/bin/bash
rpath="$(readlink $BASH_SOURCE)"
if [ -z "$rpath" ];then
    rpath=$BASH_SOURCE
fi
root="$(cd $(dirname $rpath) && pwd)"
cd "$root"

user=${SUDO_USER:-$(whoami)}
home=$(eval echo ~$user)

red=$(tput setaf 1)
green=$(tput setaf 2)
reset=$(tput sgr0)

exit_file_not_exist=1
exit_changed=2
exit_not_changed=3

usage(){
    cat<<-EOF
	Usage: $(basename $0) CMD
	CMD:
	    start
	    stop
	    status
	    config
	    em
	    ping
	    check
	EOF
    exit 1
}

start(){
    #tmux new-session -d -s "ssr local" python ROOT/local.py -c ROOT/config-local.json
    case $(uname) in
        Linux)
            if (($EUID!=0));then
                sudo systemctl start ssrlocal
            else
                systemctl start ssrlocal
            fi
            ;;
        Darwin)
            launchctl load -w $home/Library/LaunchAgents/ssrlocal.plist
            ;;
    esac
}

stop(){
    #tmux kill-session -t "ssr local"
    case $(uname) in
        Linux)
            if (($EUID!=0));then
                sudo systemctl stop ssrlocal
            else
                systemctl stop ssrlocal
            fi
            ;;
        Darwin)
            launchctl unload -w $home/Library/LaunchAgents/ssrlocal.plist
            ;;
    esac
}

config(){
    if [ ! -e $root/config-local.json ];then
        cp $root/config-local.json.example $root/config-local.json
    fi
    modify "$root/config-local.json"
    case $? in
        $exit_file_not_exist)
            echo "config file not exist"
            ;;
        $exit_changed)
            echo "Config file changed,restart service..."
            stop
            start
            echo "Done."
            ;;
        $exit_not_changed)
            echo "Nothing happened."
            ;;
    esac
}

modify(){
    f=$1
    if [ -z "$f" ];then
        return $exit_file_not_exist
    fi
    editor=vi
    if command -v vim >/dev/null 2>&1;then
        editor=vim
    fi
    case $(uname) in
        Linux)
            STAT=stat
            ;;
        Darwin)
            STAT='stat -x'
            ;;
    esac
    #get mtime
    mtime_before="$($STAT $f | grep Modify)"
    $editor $f
    mtime_after="$($STAT $f | grep Modify)"
    if [[ ${mtime_before} != ${mtime_after} ]];then
        # echo "config file changed,restart..."
        # stop
        # start
        return $exit_changed
    else
        # echo "Nothing happened."
        return $exit_not_changed
    fi
}

ping(){
    server="$(python parseConfig.py config-local.json server)"
    if [ -n "$server" ];then
        echo "Try to $(tput bold)ping$(tput sgr0) server: $(tput setaf 1)$server$(tput sgr0)..."
        /usr/bin/ping -c 8 "$server"
    fi
}

check(){
    server="$(python parseConfig.py config-local.json server 2>/dev/null)"
    localPort="$(python parseConfig.py config-local.json local_port 2>/dev/null)"
    if [ -z "$server" ];then
        echo "Canot find out server in config-local.json"
        return 1
    fi
    if echo "$server" | grep -qE '^[0-9]+(\.[0-9]+){3}$';then
        echo "Server: ${green}$server${reset} is ip address"
        serverIP="$server"
        echo "Server ip: ${green}$serverIP${reset}"
    else
        echo -e "Server: ${green}$server${reset} is domain name,\ntry to lookup its ip address..."
        serverIP="$(nslookup $server | perl -ne 'print $1 if/^Address\s*:\s*(\d+(\.\d+){3})$/')"
        echo "Get server ip by nslookup: ${green}$serverIP${reset}"
    fi
    echo "Local port: ${green}$localPort${reset}"
    echo "-------------------------------------------"
    echo "Try to get ip from curl by proxy: socks5://localhost:$localPort..."
    serverFromCurl="$(curl -m 3 -sx socks5://localhost:$localPort cip.cc | perl -ne 'print $1 if /^\s*IP\s*:\s*(\d+(\.\d+){3})\s*$/' 2>/dev/null)"
    if [ -z "$serverFromCurl" ];then
        echo "${red}Cannot get ip from curl,proxy not turn on?${reset}"
        return 1
    fi
    echo "Server ip from curl: ${green}$serverFromCurl${reset}"
    echo "-------------------------------------------"
    if [[ "$serverIP" == "$serverFromCurl" ]];then
        echo "${green}OK.${reset}"
    else
        echo "${red}Failed.${reset}"
    fi
}

editMyself(){
    editor=vi
    if command -v vim >/dev/null 2>&1;then
        editor=vim
    fi
    $editor $root/ssrlocal
}

status(){
    case $(uname) in
        Linux)
            systemctl status ssrlocal
            ;;
        Darwin)
            launchctl list | grep ssrlocal
            ;;
    esac
}

cmd=$1

case $cmd in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        stop
        start
        ;;
    config)
        config
        ;;
    em)
        editMyself
        ;;
    ping)
        ping
        ;;
    check)
        check
        ;;
    *)
        usage
        ;;
esac
